import SortLayer from "./sortlayer"
import axios from 'axios';
import { uuid } from "@/assets/js/utils/Uuid"

/**
 * 说明
 * 1、关于图层排序问题
 *  首页要注册图层到这个排序工厂（管理中心）
 *  最重要的是type类型，从小到大的int数值，代表这从上到下的图层位置关系，最小的在最上方
 *  最大的在最下方，通过调节this.ref的值来决定插入图层位置；
 *  
 * ref = 1
 * 
 *  0  1   2   3   4     地图已经添加
 *    0  1   2   3   4   即将添加的图层
 * 
 *  ref = 0
 * 
 *  0  1  2  3  4        地图已经添加
 *  0  1  2  3  4        即将添加的图层
 * 
 * 
 *  ref = 2
 *  0   1   2   3   4            地图已经添加
 *        0   1   2    3   4     即将添加的图层
 * 
 * 
 */
export default class SortFactory {


    constructor(map) {
        this.map = map
        this.layers = {
            "mapbox-gl-draw-cold": new SortLayer("mapbox-gl-draw-cold", 0, "mapbox-gl-draw"),
            "mapbox-gl-draw-hot": new SortLayer("mapbox-gl-draw-hot", 0, "mapbox-gl-draw"),

        } //k:source v:SortLayer

        this.isSort = false;

        this.callback = undefined;
        this.ref = 1;
    }

    getMapId() {
        return this.map._mapId;
    }

    bindEvent(id) {
        this._mouseEnter1 = this._mouseEnter.bind(this, id)
        this._mouseELeave1 = this._mouseELeave.bind(this, id);
        this._mouseClick1 = this._mouseClick.bind(this, id);
    }




    setOnMapClickListener(callback) {
        this.callback = callback;
    }

    //鼠标
    _mouseEnter(id, e) {
        this.map.getCanvas().style.cursor = 'Pointer';
        this.callback && this.callback("enter", e)
    }

    //
    _mouseELeave(id, e) {
        this.map.getCanvas().style.cursor = '';
        this.callback && this.callback("leave", e)
    }

    _mouseClick(id, e) {
        this.callback && this.callback("click", e)
        //高亮
        this.setHLFilter(id, e.features[0].id || e.features[0].properties.ID)
    }



    //注册到排序管理中，交个这个类管理
    registerAllLayers(layers) {
        for (let i = 0; i < layers.length; i++) {
            this.addSortLayer(layers[i]._id, layers[i].sort, layers[i].name, layers[i]);
        }
    }
    
   //移除排序图层
    removeSortLayer(sourceID){
        if(this.layers[sourceID]){
            delete this.layers[sourceID];
        }
    }

    //添加排序图层
    addSortLayer(sourceId, type, name, layer) {
        //添加到layers中去
        this.layers[sourceId] = new SortLayer(sourceId, type, name, layer);

        //排序
    }


    //获取自定的排序图层
    getSortLayer(sourceId) {
        return this.layers[sourceId];
    }

    //系统排序
    _getOrder() {
        return this.map.style._order;
    }

    //系统图层
    _getLayers() {
        return this.map.style._layers
    }


    //获取BeforeID  没有添加类型内排序
    getSortLayerBeforeId(sourceId) {
        var order = this._getOrder();
        var layers = this._getLayers();
        var array = []; //
        var sf = []

        // for (let i = order.length - 1; i >= 0; i--) {
        for (let i = 0; i < order.length; i++) {
            try {

                let layerId = order[i]; //遍历 order表
                let source = layers[layerId].source//找到图层 数据源
                let sl = this.layers[source]; //获取自定包装类sortlayer
                let currSl = this.getSortLayer(sourceId);//要添加的图层
                if (!sl || !currSl) {
                    continue
                }
                let index = currSl.getType() - sl.getType();
                //目标和当前的类型做差,做成集合，然后取出最小值。
                if (index >= 0 && !array[index]) {
                    array[index] = layerId;
                    sf[index] = sl;
                }
            } catch (e) {
                console.log(e)
            }
        }

        for (let i = this.ref < array.length && this.ref; i < array.length; i++) {
            if (array[i]) {
                //console.log(this.map,sf[i],this.layers)
                return array[i]
            }
        }
        // console.log(this.map,undefined,this.layers)
        return undefined;

    }


    //超图接法
    async addSuperMapLayerByUrl(id, url, minZoom, maxZoom, isQuery) {
        var data = this.getSortLayer(id).getSuperMapData();
        if (data) {
            var layers = data.layers;
            for (var i = 0; i < layers.length; i++) {
                layers[i].source = id;
                if (isQuery && this.getSortLayer(id).isClickable()) {
                    this.bindEvent(id);
                    this.map.on('click', layers[i].id, this._mouseClick1);
                    this.map.on('mouseenter', layers[i].id, this._mouseEnter1)
                    this.map.on('mouseleave', layers[i].id, this._mouseELeave1)
                }
            }
            this.map.addStyle(data, this.getSortLayerBeforeId(id), minZoom, maxZoom);
        } else {
            //ajax
            var res = await axios.get(url);
            // console.log(res)
            this.addSuperMapLayer(id, res.data, minZoom, maxZoom, isQuery);
        }
    }


    //超图接法
    addSuperMapLayer(id, data, minZoom, maxZoom, isQuery) {
        var sources = data.sources;
        data.name = id;
        var layers = data.layers;
        if (!sources[id]) {
            for (const key in sources) {   //只能存在唯一数据源
                if (sources.hasOwnProperty(key)) {
                    const element = sources[key];
                    sources[id] = element;
                    delete sources[key];
                }
            }
        }

        for (var i = 0; i < layers.length; i++) {
            layers[i].source = id;
            if (isQuery && this.getSortLayer(id).isClickable()) {
                this.bindEvent(id);
                this.map.on('click', layers[i].id, this._mouseClick1);
                this.map.on('mouseenter', layers[i].id, this._mouseEnter1)
                this.map.on('mouseleave', layers[i].id, this._mouseELeave1)
            }
        }

        const sourcelayers = data.layers.filter(i => i['source-layer']);
        const sourceLayer = sourcelayers.length > 0 ? sourcelayers[0]['source-layer'] : undefined;

        if (sourceLayer) {
            //高亮图层(mvt瓦片)
            const hidghtlayers = [
                {
                    id: `${id}-hightlight_p`,
                    source: id,
                    type: "circle",
                    paint: {
                        "circle-radius": 6,
                        "circle-color": "#ff0000",
                        "circle-opacity": 1,
                        "circle-stroke-width": 2,
                        "circle-stroke-color": "#ff0000",
                        "circle-stroke-opacity": 0.5
                    },
                    "source-layer": sourceLayer,
                    filter: ['all', ["==", "$type", "Point"], ['==', 'SmID', ""]]
                },
                {
                    id: `${id}-hightlight_l`,
                    source: id,
                    type: "line",
                    paint: {
                        "line-color": "#ff0000",
                        "line-width": 3,
                        "line-opacity": 0.75,
                        "line-color": "#F5E301",
                        "line-width": 9
                    },
                    "source-layer": sourceLayer,
                    // filter: ["==", "$type", "LineString"]
                    filter: ['all', ["==", "$type", "LineString"], ['==', 'id', 4370]]
                },
                {
                    id: `${id}-hightlight_r`,
                    source: id,
                    type: "fill",
                    paint: {
                        "fill-color": "#9DC0F8",
                        "fill-opacity": 0.7

                    },
                    "source-layer": sourceLayer,
                    filter: ['all', ["==", "$type", "Polygon"], ['==', 'id', '']]
                }];
            data.layers = data.layers.concat(hidghtlayers);
        }




        //保存超图接法数据
        var sortLayer = this.getSortLayer(id);
        if (!sortLayer) {
            console.warn("未注册数据源ID为：\"" + id + "\"的图层！！！")
            return;
        }
        sortLayer.setSuperMapData(data)
        //添加图层

        this.map.addStyle(data, this.getSortLayerBeforeId(id), minZoom, maxZoom);
    }


    //设置高亮过滤器
    setHLFilter(id, featureID) {

        const filterP = this.map.getFilter(`${id}-hightlight_p`);
        const filterL = this.map.getFilter(`${id}-hightlight_l`);
        const filterR = this.map.getFilter(`${id}-hightlight_r`);

        filterP[2] = ['any', ['==', 'ID', featureID ? featureID : ""], ['==', 'SmID', featureID ? featureID : ""]];
        filterL[2] = ['any', ['==', 'ID', featureID ? featureID : ""], ['==', 'SmID', featureID ? featureID : ""]];
        filterR[2] = ['any', ['==', 'ID', featureID ? featureID : ""], ['==', 'SmID', featureID ? featureID : ""]];

        this.map.setFilter(`${id}-hightlight_p`, filterP);
        this.map.setFilter(`${id}-hightlight_l`, filterL);
        this.map.setFilter(`${id}-hightlight_r`, filterR);


    }


    //添加GEOJSON图层

     addGeoJsonLayer(id, data) {

        for (const key in data.sources) {
            if (data.sources.hasOwnProperty(key)) {
                const element = data.sources[key];

                if (!this.map.getSource(key)) {
                    this.map.addSource(id, element);
                }
            }
        }
        var beforeid = this.getSortLayerBeforeId(id)

        for (let i = 0; i < data.layers.length; i++) {
            if (!this.map.getLayer(data.layers[i].id)) {
                //添加
                if (data.layers[i] && data.layers[i]['symUrl']) {
                    var iconUrl = data.layers[i]['symUrl'];
                    // console.log(iconUrl, this.getMapId())
                    if(!data.layers[i].layout['icon-image']){
                        data.layers[i].layout['icon-image'] = uuid();
                    } 
                    this.map.loadImage(iconUrl, (err, img) => {
                        if (err) return;
                        if (!this.map.hasImage(data.layers[i].layout['icon-image'])) {
                            this.map.addImage(data.layers[i].layout['icon-image'], img);
                           
                        }
                    })
                }
                this.map.addLayer(data.layers[i], beforeid);

                if (this.getSortLayer(id).isClickable()) {
                    this.bindEvent(id);
                    this.map.on('click', data.layers[i].id, this._mouseClick1);
                    this.map.on('mouseenter', data.layers[i].id, this._mouseEnter1)
                    this.map.on('mouseleave', data.layers[i].id, this._mouseELeave1)
                }
            }
        }


        const hidghtlayers = [
            {
                id: `${id}-hightlight_p`,
                source: id,
                type: "circle",
                paint: {
                    "circle-radius": 6,
                    "circle-color": "#ff0000",
                    "circle-opacity": 1,
                    "circle-stroke-width": 2,
                    "circle-stroke-color": "#ff0000",
                    "circle-stroke-opacity": 0.5
                },

                filter: ['all', ["==", "$type", "Point"], ['==', '_id', ""]]
            },
            {
                id: `${id}-hightlight_l`,
                source: id,
                type: "line",
                paint: {
                    "line-color": "#ff0000",
                    "line-width": 3,
                    "line-opacity": 0.75,
                    "line-color": "#F5E301",
                    "line-width": 9
                },
                // "source-layer": id,
                // filter: ["==", "$type", "LineString"]
                filter: ['all', ["==", "$type", "LineString"], ['==', 'id', 4370]]
            },
            {
                id: `${id}-hightlight_r`,
                source: id,
                type: "fill",
                paint: {
                    "fill-color": "#9DC0F8",
                    "fill-opacity": 0.7

                },
                //"source-layer": id,
                filter: ['all', ["==", "$type", "Polygon"], ['==', 'id', '']]
            }];

        for (let i = 0; i < hidghtlayers.length; i++) {
            this.map.addLayer(hidghtlayers[i], beforeid);
        }

    }


    //原生接法
    addLayer(id, layer, isQuery) {
        this.map.addLayer(layer, this.getSortLayerBeforeId(id))
        if (isQuery && this.getSortLayer(id).isClickable()) {
            this.bindEvent(id);
            this.map.on('click', id, this._mouseClick1);
            this.map.on('mouseenter', id, this._mouseEnter1)
            this.map.on('mouseleave', id, this._mouseELeave1)
        }

    }


    //移除瓦片
    removeLayer(sourceId) {

        if (!this.layers[sourceId]) {
            console.warn("ID:" + sourceId + "的图层数据未注册到图层管理器")
            return;
        }
        let source = this.map.getSource(sourceId);
        let layers = this.map.getStyle().layers;
        if (!source) {
            console.warn('移除矢量瓦片,数据源ID "' + sourceId + '" sourceID 不存在');
            return;
        }
        for (let i = 0; i < layers.length; i++) {
            if (layers[i].source === sourceId) {
                this.map.removeLayer(layers[i].id);
                this.map.off('click', this._mouseClick);
                this.map.off('mouseenter', this._mouseEnter)
                this.map.off('mouseleave', this._mouseELeave)

            }
        }

        this.map.removeSource(sourceId);

    }


    //获取source-layer 的名称
    getSourceLayerName(sourceID) {
        return this.layers[sourceID] && this.layers[sourceID].getSourceLayerName();
    }

    //自定义json
    /**
     * 说明
     * 
     * {
     *   layers:[]
     *   datasource:"http://localhost:3000/api",
     *   sources:{
     *     "shujuyuan":{}
     *   }
     * }
     * 
     * 
     * @param {*} id 
     * @param {*} url 
     * @param {*} minZoom 
     * @param {*} maxZoom 
     * @param {*} isQuery 
     */
    async addHgcCustomLayer(id, url, minZoom, maxZoom, isQuery, filter) {

        var sortLayer = this.getSortLayer(id);
        var data = sortLayer.getSuperMapData();

        if (data) {
            var layers = data.layers;
            for (var i = 0; i < layers.length; i++) {
                layers[i].source = id;
                layers[i].id = uuid();
            }

            var datasource = await this.requestData(data.datasource, filter); //添加过滤条
            var geojson = { type: "geojson", data: { type: "FeatureCollection", features: datasource.data.data.data } };

            sortLayer.setGeoJsonData(datasource.data.data.data);   //geojson数据记录
            var sources = {};
            sources[id] = geojson;
            this.addGeoJsonLayer(id, { layers: data.layers, sources: sources });
        } else {
            //ajax
            var res = await axios.get(url);
            var resource = res.data.data.resource;
            try {
                resource = JSON.parse(resource);
            } catch (e) {
                resource = {};
            }

            //保存超图接法数据
            var sortLayer = this.getSortLayer(id);
            if (!sortLayer) {
                console.warn("未注册数据源ID为：\"" + id + "\"的图层！！！");
                return;

            }
            sortLayer.setSuperMapData(resource)
            this.addHgcCustomLayer(id, url, minZoom, maxZoom, isQuery, filter);
        }
    }

    //请求数据
    /**
     * 
     * @param {*} url 
     * @param {*} filter  query
     * @param {*} body    body
     */
    async requestData(url, filter, body) {

        if (filter && typeof filter === "object") {
            for (const key in filter) {
                if (filter.hasOwnProperty(key)) {
                    const element = filter[key];
                    if (url.indexOf('?') > 0) {
                        url += "&" + key + "=" + element;
                    } else {
                        url += "?";
                        url += "&" + key + "=" + element;
                    }
                }
            }
        }

        return await axios.post(url, body);

    }

    /**
     * 获取自定义图层的数据（包含分页）
     * @param {数据源ID} id 
     * @param {过滤条件} filter 
     */
    async getHgcCustomData(id, filter, opt) {
        let data = this.layers[id] && this.layers[id].getSuperMapData();
        return await this.requestData(data && data.datasource, filter, opt);
    }




}